package storage.buffer;

import java.nio.ByteBuffer;
import java.util.LinkedList;

import storage.file.Block;
import storage.file.BlockID;
import storage.file.FileManagerFactory;
import utils.Lib;

public class SimpleBufferManager extends AbstractBufferManager {
	
	static {
		identifier = SimpleBufferManager.class.getCanonicalName();
	}
	
	LinkedList<BlockID> pages = new LinkedList<BlockID>();
	LinkedList<BlockID> pinPages = new LinkedList<BlockID>();;

	@Override
	public Block allocatePage(BlockID pageID) {
		if (bufferPool.containsKey(pageID))
			return bufferPool.get(pageID);
		
		if (size == BUFFER_SIZE) {
			// replacement
			if (pages.size() > 0)
				deallocatePage(pages.getFirst());
			else
				System.err.println("No space for new pages");
		}
		Block page = FileManagerFactory.getFileManager().read(pageID);
		bufferPool.put(pageID, page);
		pages.addLast(pageID);
		++size;
		return page;
	}

	@Override
	public void deallocatePage(BlockID pageID) {
		Lib.assertTrue(bufferPool.containsKey(pageID));
		Lib.assertTrue(pages.contains(pageID));
		
		FileManagerFactory.getFileManager().write(pageID, bufferPool.remove(pageID));
		pages.remove(pageID);
		--size;
	}

	@Override
	public void pinPage(BlockID pageID) {
		if (!pinPages.contains(pageID) && pages.contains(pageID)) {
			pages.remove(pageID);
			pinPages.add(pageID);
		}
	}

	@Override
	public void unpinPage(BlockID pageID) {
		Lib.assertTrue(pinPages.contains(pageID) && !pages.contains(pageID));
		pinPages.remove(pageID);
		pages.addLast(pageID);
	}

	@Override
	public boolean writePage(BlockID pageID, ByteBuffer data) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean readPage(BlockID pageID, ByteBuffer data) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean flushAll() {
		// TODO Auto-generated method stub
		return false;
	}

}
